﻿#define _CRT_SECURE_NO_WARNINGS 1

#include"Sort.h"


void Print(int*a , int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
}

void CreatNDate()
{
	//造数据
	int n = 1000000;
	//设置随机种子
	srand((unsigned int)time(NULL));
	//存放数据的文件名
	const char* file = "data.txt";
	//以写的形式打开文件
	FILE* fin = fopen(file, "w");
	if (fin == NULL)
	{
		perror("fopen fail");
		exit(-1);
	}
	//将数据写入文件当中
	for (int i = 0; i < n; i++)
	{
		fprintf(fin, "%d\n", i + rand());
	}
	//关闭文件
	fclose(fin);
	fin = NULL;
}

//qsort 的比较函数
int compare(const void* e1, const void* e2)
{
	return *(int*)e1 - *(int*)e2;
}

//返回在file 中实际读到的数据的个数,没有读到数据便返回0
int ReadNDataSortToFile(FILE* fout, int n, const char* file1)
{
	//将从file 中读取的数据先放在变量x中
	int x = 0;
	//创建数组
	int* a = (int*)malloc(sizeof(int) * n);
	if (a == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}

	//想要读取 n 个数据，变量用来记录读取到的数据的个数
	int j = 0;
	for (int i = 0; i < n; i++)
	{
		//需要判断读取是否成功
		if (fscanf(fout, "%d", &x) == EOF)
			break;

		//将读取的数据放到数组之中
		a[j++] = x;
	}
	//如果没有读取到数据便返回0
	if (j == 0)
		return 0;

	//在内存中排序 - 此处使用到了qsort
	qsort(a, j, sizeof(int), compare);

	//打开文件file1 
	FILE* fin = fopen(file1, "w");
	if (fin == NULL)
	{
		perror("ReadNDataSortToFile - fopen file1 fail");
		exit(-1);
	}
	//将排好的数据放到文件file1 中
	for (int i = 0; i < j; i++)
	{
		fprintf(fin, "%d\n", a[i]);
	}
	//释放动态开辟的空间
	free(a);
	a = NULL;
	//关闭file1 
	fclose(fin);
	fin = NULL;

	//返回读取的数据䣌个数
	return j;
}

//文件归并排序
void MergeFile(const char* file1, const char* file2, const char* mfile)
{
	//打开file1 
	FILE* fout1 = fopen(file1, "r");
	if (fout1 == NULL)
	{
		perror("fopen file1 fail");
		exit(-1);
	}

	//打开file2 
	FILE* fout2 = fopen(file2, "r");
	if (fout2 == NULL)
	{
		perror("fopen file2 fail");
		exit(-1);
	}

	//打开mfile
	FILE* fin = fopen(mfile, "w");
	if (fin == NULL)
	{
		perror("fopen mfile fail");
		exit(-1);
	}
	
	//将file1 与 file2 进行归并，将归并的结果放到mfile 之中
	//由于file1 与 file2 之中的数据个数可能不一样，需要创建变量来接收从这两个文件中读取到的数据的返回值
	//然后判断读取是否成功
	int x1 = 0;
	int x2 = 0;
	int ret1 = fscanf(fout1, "%d", &x1);
	int ret2 = fscanf(fout2, "%d", &x2);
	while (ret1 != EOF && ret2 != EOF)
	{
		if (x1 < x2)
		{
			fprintf(fin, "%d\n", x1);
			ret1 = fscanf(fout1, "%d", &x1);
		}
		else
		{
			fprintf(fin, "%d\n", x2);
			ret2 = fscanf(fout2, "%d", &x2);
		}
	}
	while (ret1 != EOF)
	{
		fprintf(fin, "%d\n", x1);
		ret1 = fscanf(fout1, "%d", &x1);
	}

	while (ret2 != EOF)
	{
		fprintf(fin, "%d\n", x2);
		ret2 = fscanf(fout2, "%d", &x2);
	}
	//关闭文件
	fclose(fout1);
	fclose(fout2);
	fclose(fin);

}

void Test2()
{
	//创建待排序的大文件
	//CreatNDate();

	//文件
	const char* file1 = "file1.txt";
	const char* file2 = "file2.txt";
	const char* mfile = "mfile.txt";

	//打开待排序的文件
	FILE* fout = fopen("data.txt", "r");
	if (fout == NULL)
	{
		perror("fopen file fail");
		exit(-1);
	}
	
	//从fout 读取n个数据放到file1 file2 之中
	int n = 10000;
	ReadNDataSortToFile(fout, n, file1);
	ReadNDataSortToFile(fout, n, file2);

	while (1)
	{
		//将file1 与file2 进行归并
		MergeFile(file1, file2, mfile);

		//删除file1 file2 
		remove(file1);
		remove(file2);

		//将mfile 重命名为file1 
		int h = rename(mfile, file1);

		//再读取n个数据放到file2 之中
		//可能读不到数据，需要判断读取数据这个函数的返回值
		int m = 0;
		if ((m= ReadNDataSortToFile(fout, n, file2))== 0)
			break;

		if (n < 100)
		{
			int x = 0;
		}
	}
}

void test1()
{
	//int arr[] = { 2,10,8,1 };
	int arr[] = { 2,9,18,32,67,12,9,3,75,25,9,18,21,34 };
	int sz = sizeof(arr) / sizeof(arr[0]);

	Print(arr, sz);
	//InsertSort(arr, sz);
	//ShellSort(arr, sz);
	//SelectSort(arr, sz);
	//BubbleSort(arr, sz);
	//MergeSort(arr, sz);
	//MergeSortNonR(arr, sz);
	CountSort(arr, sz);
	Print(arr, sz);
}

int main()
{
	test1();
	//CreatNDate();
	//Test2();
	return 0;
}